// Copyright (c) 2022 Presto Labs Pte. Ltd.
// Author: leon

#pragma once

#include <map>
#include <memory>
#include <string>
#include <vector>

#include <rapidjson/document.h>

// internal
#include "coin2/exchange/base/feed/processor.h"
#include "coin2/exchange/base/market/enums.h"
#include "coin2/exchange/di/constant.h"

namespace coin2::exchange::mexc::feed_v2 {
namespace impl {
using coin2::exchange::base::executor::TopicRecordPacket;
using namespace coin2::exchange::base::symbology;
class MexcFeedProcessor : public base::feed::FeedParsingProcessor {
 public:
  explicit MexcFeedProcessor(
      const std::string& system_name,
      const coin2::exchange::di::ConstantInjection& ci,
      const feed::RawParserConfig& config,
      const MarketExchangeApi& mea)
      : FeedParsingProcessor(
            system_name,
            mea,
            ci,
            config,
            "cc/coin2/exchange/mexc/feed_v2/schema.json") {}
  void OnTopicRecord(const base::executor::TopicRecordPacket& packet) override;
  std::string ExtractChannel(const rapidjson::Document& doc) {
    if (doc.HasMember("url")) {
      const std::string url = doc["url"].GetString();
      static constexpr std::string_view kline_url("klines?");
      static constexpr std::string_view interval("interval=");
      if (url.rfind(kline_url) != std::string::npos) {
        size_t pos = url.find(interval);
        size_t sep = url.find("&", pos + 1);
        std::string channel_identity = url.substr(pos, sep - pos);
        if (!CheckChannelFilter("?symbol={}&" + channel_identity)) {
          return "unknown";
        }

        return "kline_rest";
      }
    }
    if (!doc.HasMember("channel")) {
      return "unknown";
    }
    const std::string& channel = doc["channel"].GetString();
    if (channel == "push.depth.aggregate") {
      return "book";
    } else if (channel == "push.limit.depth") {
      return "limited_depth";
    } else if (channel == "push.depth") {
      return "incremental_depth";
    } else if (channel == "push.deal.aggregate") {
      return "trade";
    } else {
      return "unknown";
    }
  }
};
}  // namespace impl
using impl::MexcFeedProcessor;
}  // namespace coin2::exchange::mexc::feed_v2
